package com.example.utils;

import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.toolkit.LambdaUtils;
import com.baomidou.mybatisplus.core.toolkit.support.ColumnCache;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.lang.reflect.Field;
import java.util.*;

/**
 * 使用MybatisPlus实现更新置空工具类
 * @author wanghongyu02
 * @date 2024-07-25 17:27
 */
@Component
public class CrmUpdateGenerator {


    @Resource
    SqlSessionFactory sqlSessionFactory;

    /**
     * 创建UpdateWrapperGenerator
     *
     * @param entity           实体
     * @param entityClass      实体类
     * @param mapperType
     * @param ignoreProperties 属性
     * @return
     */
    public <T> UpdateWrapper createUpdateWrapper(T entity, Class<T> entityClass, Class<? extends BaseMapper<T>> mapperType, String... ignoreProperties) {
        UpdateWrapper updateWrapper = new UpdateWrapper<>();
        List<Field> fields = getAllFields(entityClass);

        // 对应Mapper缓存添加是懒加载 若首次调用 不调用此方法  无法获取到COLUMN_CACHE_MAP映射
        sqlSessionFactory.getConfiguration().addMapper(mapperType);
        // 获取字段映射
        Map<String, ColumnCache> columnMap = LambdaUtils.getColumnMap(entityClass);

        for (Field field : fields) {
            try {
                field.setAccessible(true);
                Object value = field.get(entity);
                boolean isIgnore = false;
                for (String ignoreProperty : ignoreProperties) {
                    if (ignoreProperty.equals(field.getName())) {
                        isIgnore = true;
                        break;
                    }
                }

                if (isIgnore) {
                    continue;
                }

                TableField annotation = field.getAnnotation(TableField.class);
                if (Objects.nonNull(annotation)){
                    if (!annotation.exist()){
                        continue;
                    }
                }
                // 拼装字段
                ColumnCache columnCache = columnMap.get(LambdaUtils.formatKey(field.getName()));
                if (Objects.nonNull(columnCache)){
                    updateWrapper.set(columnCache.getColumn(), value);
                }
            } catch (IllegalAccessException e) {
                throw new RuntimeException(e);
            }
        }

        return updateWrapper;
    }

    /**
     * 获取对象的字段列表
     * @author wanghongyu02
     * @date 2024-07-24 15:10
     * @param clazz
     * @return java.util.List<java.lang.reflect.Field>
     */
    public List<Field> getAllFields(Class<?> clazz) {
        List<Field> fields = new ArrayList<>();
        while (clazz != null) {
            fields.addAll(Arrays.asList(clazz.getDeclaredFields()));
            clazz = clazz.getSuperclass();
        }
        return fields;
    }
}
